package com.anmong.cloud.cloudcommon.init;

import com.github.yitter.contract.IdGeneratorOptions;
import com.github.yitter.idgen.YitIdHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

/**
 * 机器id,用_分割,示例1_00_0,1_01_1,必须保证全局唯一，可以通过WorkerIdBitLength来控制，最大值为15，
 * 这里使用13，也就是说最大数是8196个机器,可用512年，按经规则分成三个部分
 * 第一部分：可用区（机房id）,位数为1，最大值为8，最小值为0，也就说是最多有8个云服务器可用区，
 * 第二部分：机器id，位数为2，最大值为99，为避免浪费，位数为1也用0填充，如01
 * 第三部分：应用实例id，位数为1，最大值为9，最小值为0，一个机器应该不会不是10个及以上的jar实例吧？
 * 三个部分拼接成一个完整的workerid，为避免浪费，机器id和实例id建议从0开始
 * 若还有更多机器需求，WorkerIdBitLength^2最大值为两万多，已经是超大型型的系统，应该不会再用雪花id算法了
 **/
@Component
@Slf4j
public class IdGeneratorInit implements CommandLineRunner {


    @Value("${anmong.worker-id}")
    private String workerId;
    @Override
    public void run(String... args) throws Exception {
        String[] workerIds = workerId.split("_");
        if (workerIds.length != 3){
            throw new Exception("可用区(机房)id不正确，请按规则配置anmong.worker-id,示例1_00_0");
        }
        if (workerIds[0].length() != 1){
            throw new Exception("可用区(机房)id不正确，请按规则配置anmong.worker-id,示例1_00_0");
        }
        Integer areaId = Integer.valueOf(workerIds[0]);
        if (areaId < 1){
            throw new Exception("可用区不能小于1");
        }
        if (areaId > 8){
            throw new Exception("可用区不能大于8");
        }
        if (workerIds[1].length() != 2){
            throw new Exception("可用区(机房)id不正确,请按规则配置anmong.worker-id,示例1_00_0");
        }
        if (!"00".equals(workerIds[1])){
            try {
                Integer machineId = Integer.valueOf(workerIds[1]);
                if (machineId < 0){
                    throw new Exception("机器id不正确，请按规则配置anmong.worker-id,示例1_00_0");
                }
            }
            catch (Exception e){
                log.error("机器id配置不正确:{}",workerIds[1]);
                throw new Exception("机器id不正确，请按规则配置anmong.worker-id,示例1_00_0");
            }
        }
        if (workerIds[2].length() != 1){
            throw new Exception("应用实例id不正确，请按规则配置anmong.worker-id,示例1_00_0");
        }
        Short workerId = Short.valueOf(workerIds[0]+workerIds[1]+workerIds[2]);
        log.info("ATTENTION!!!!!!!!!!!!!");
        log.info("ATTENTION!!!!!!!!!!!!!");
        log.info("当前实例workerId为:{},请注意核实是否重复!",workerId);
        log.info("ATTENTION!!!!!!!!!!!!!");
        log.info("ATTENTION!!!!!!!!!!!!!");
        // 创建 IdGeneratorOptions 对象，可在构造函数中输入 WorkerId：
        IdGeneratorOptions options = new IdGeneratorOptions(workerId);
        // options.WorkerIdBitLength = 10; // 默认值6，限定 WorkerId 最大值为2^6-1，即默认最多支持64个节点。
        options.WorkerIdBitLength = 13;
        // options.SeqBitLength = 6; // 默认值6，限制每毫秒生成的ID个数。若生成速度超过5万个/秒，建议加大 SeqBitLength 到 10。
        // options.BaseTime = Your_Base_Time; // 如果要兼容老系统的雪花算法，此处应设置为老系统的BaseTime。
        // ...... 其它参数参考 IdGeneratorOptions 定义。

        // 保存参数（务必调用，否则参数设置不生效）：
        YitIdHelper.setIdGenerator(options);
    }
}
